package org.nf.web.servlet.param;

import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializer;
import org.nf.web.servlet.MethodArgumentResolver;
import org.nf.web.servlet.ServletApi;
import org.nf.web.servlet.annotation.RequestBody;

import java.io.BufferedReader;
import java.lang.reflect.Parameter;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * @author wangl
 * @date 2024/4/3
 * 负责解析带有RequestBody注解的请求体参数
 */
public class RequestBodyMethodArgumentResolver implements MethodArgumentResolver {

    @Override
    public boolean supports(Parameter parameter) {
        return parameter.isAnnotationPresent(RequestBody.class);
    }

    @Override
    public Object resolve(Parameter parameter, ServletApi servletApi) throws Exception {
        String pattern = parameter.getAnnotation(RequestBody.class).dateFormat();
        GsonBuilder builder = new GsonBuilder();
        if(!"".equals(pattern)) {
            setDateFormat(builder, pattern);
        }
        String requestBody = getRequestBody(servletApi);
        return builder.create().fromJson(requestBody, parameter.getType());
    }

    /**
     * 读取请求体的内容
     * @param servletApi 封装的Request和Response
     * @return 请求体内容
     * @throws Exception 异常信息
     */
    private String getRequestBody(ServletApi servletApi) throws Exception{
        BufferedReader reader = servletApi.request().getReader();
        StringBuilder requestBody = new StringBuilder();
        String str;
        while((str = reader.readLine()) != null) {
            requestBody.append(str);
        }
        return requestBody.toString();
    }

    /**
     * 设置反序列的日期格式
     * @param builder gsonBuilder
     * @param pattern 日期格式化
     */
    private void setDateFormat(GsonBuilder builder, String pattern) {
        builder.setDateFormat(pattern);
        //构建LocalDateTime的json反序列化器
        JsonDeserializer<LocalDateTime> localDateTimeJsonDeserializer = (jsonElement, type, jsonDeserializationContext) ->
                LocalDateTime.parse(jsonElement.getAsString(), DateTimeFormatter.ofPattern(pattern));
        builder.registerTypeAdapter(LocalDateTime.class, localDateTimeJsonDeserializer);
        //构建LocalDate的json反序列化器
        JsonDeserializer<LocalDate> localDateJsonDeserializer = (jsonElement, type, jsonDeserializationContext) ->
                LocalDate.parse(jsonElement.getAsString(), DateTimeFormatter.ofPattern(pattern));
        builder.registerTypeAdapter(LocalDate.class, localDateJsonDeserializer);
        //构建LocalTime的json反序列化器
        JsonDeserializer<LocalTime> localTimeJsonDeserializer = (jsonElement, type, jsonDeserializationContext) ->
                LocalTime.parse(jsonElement.getAsString(), DateTimeFormatter.ofPattern(pattern));
        builder.registerTypeAdapter(LocalTime.class, localTimeJsonDeserializer);
    }
}